package client;

import java.rmi.RemoteException;

import communication.ClientComm;
import communication.ComandoComm;


public class InputInterpreter implements Runnable {
	private ConsoleController control;
	private ClientModel client;
	private ConsoleView output;
	private ClientComm clientComm;
	private Thread interpreter;
	private String info1;
	private boolean waitingInfo1;
	private String info2;
	private boolean waitingInfo2;
	private String msg;
	
	private boolean exiting;
	
	public InputInterpreter(ConsoleController cCo, ClientModel cM, ClientComm cC) {
		control = cCo;
		client = cM;
		clientComm = cC;
		waitingInfo1 = false;
		waitingInfo2 = false;
		exiting = false;
		interpreter = new Thread(this, "ClientInputInterpreter");
		interpreter.start();
	}
	
	public void setView(View v){
		output = (ConsoleView)v;
	}

	@Override
	public synchronized void run() {
		int action;
		while(!exiting) {
			try {
				wait();
				if (!waitingInfo1 && !waitingInfo2) {
					msg = control.pollInput();
					if (client.getGameStatus().isMyTurn && !client.getGameStatus().askedConfirm) {
						if (msg.equals("in")) {
							confermaTurno();
						}
					}
					if (msg!= null && msg.length()==1) {
						action = Integer.parseInt(msg);				
						if (!client.getGameStatus().ingame) {
							if (!client.getGameStatus().loggedIn) {
								switch(action) {
								case 1: login(); break;
								case 2: creaUtente(); break;
								case 0: esci(); break;
								}
							} else {
								switch(action){
								case 1: creaRazza(); break;
								case 2: accessoPartita(); break;
								case 3: listaGiocatori(); break;
								case 4: classifica(); break;
								case 5: logout(); break;
								case 0: esci(); break;
								}
							}
						} else {
							if (!client.getGameStatus().selectedDino) {
								switch(action){
								case 1: listaDinosauri(); break;
								case 2: passaTurno(); break;
								case 3: listaGiocatori(); break;
								case 4: classifica(); break;
								case 5: logout(); break;
								case 6: uscitaPartita(); break;
								case 7: vistaLocale(); break; //seleziona un dinosauro == richiedi vista Locale per quel dino
								case 8: mappaGenerale(); break;
								case 0: esci(); break;
								}
							} else {
								switch(action){
								case 1: statoDinosauro(); break;
								case 2: muoviDinosauro(); break;
								case 3: cresciDinosauro(); break;
								case 4: deponiUovo(); break;
								case 5:	{
									client.getGameStatus().selectedDino = false;
									client.getGameStatus().idDinoSelected = 0;
									client.sveglia();
								} break;
								}
							}
						}
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public synchronized void sveglia() {
		this.notify();
	}
	
	private synchronized void readInfo(boolean dueInfo){
		waitingInfo1 = true;
		try {
			while (waitingInfo1) {
				wait();
				info1 = control.pollInput();
				waitingInfo1 = false;
			}
			if (dueInfo) {
				waitingInfo2 = true;
				while (waitingInfo2) {
					wait();
					info2 = control.pollInput();
					waitingInfo2 = false;
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void login() throws RemoteException {
		output.login();
		readInfo(true);
		client.setGiocatore(info1, info2);
		clientComm.sendRequest(ComandoComm.login.toString() + "," + info1 + "," + info2);
		info1 = null; info2 = null;
		output.sendMessage("In attesa di risposta dal server");
	}

	public void creaUtente() throws RemoteException {
		output.creaUtente();
		readInfo(true);
		client.setGiocatore(info1, info2);
		clientComm.sendRequest(ComandoComm.creaUtente.toString() + "," + info1 + "," + info2);
		info1 = null; info2 = null;
		output.sendMessage("In attesa di risposta dal server");
	}

	public void esci() {
		output.sendMessage("Bye bye");
		client.close();
		control.close();
		exiting = true;
	}

	public void creaRazza() throws RemoteException {
		output.creaRazza();
		readInfo(true);
		clientComm.sendRequest(ComandoComm.creaRazza.toString() + "," + client.getToken() + "," + info1 + "," + info2);
		info1 = null; info2 = null;
		output.sendMessage("In attesa di risposta dal server");
	}

	public void accessoPartita() throws RemoteException {
		clientComm.sendRequest(ComandoComm.accessoPartita.toString() + "," + client.getToken());
		client.getGameStatus().askedStateBeforeFight = true;
		output.sendMessage("In attesa di risposta dal server");
	}
	
	public void uscitaPartita() throws RemoteException {
		clientComm.sendRequest(ComandoComm.uscitaPartita.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
	}

	public void listaGiocatori() throws RemoteException {
		clientComm.sendRequest(ComandoComm.listaGiocatori.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
	}

	public void classifica() throws RemoteException {
		clientComm.sendRequest(ComandoComm.classifica.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
	}

	public void logout() throws RemoteException {
		clientComm.sendRequest(ComandoComm.logout.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
	}
	
	public void mappaGenerale() throws RemoteException{
		clientComm.sendRequest(ComandoComm.mappaGenerale.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
	}
	
	public void listaDinosauri() throws RemoteException{
		clientComm.sendRequest(ComandoComm.listaDinosauri.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
	}

	public void confermaTurno() throws RemoteException {
		clientComm.sendRequest(ComandoComm.confermaTurno.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
		client.getGameStatus().askedConfirm = true;
	}

	public void passaTurno() throws RemoteException {
		clientComm.sendRequest(ComandoComm.passaTurno.toString() + "," + client.getToken());
		output.sendMessage("In attesa di risposta dal server");
		client.getGameStatus().turnPassed = true;
	}
	
	public void vistaLocale() {
		output.sendMessage("Inserisci ID del dino che vuoi selezionare");
		int idDino; readInfo(false);
		try {
			idDino = Integer.parseInt(info1);
			client.getGameStatus().idDinoSelected = idDino;
			client.getGameStatus().selectedDino = true;
			clientComm.sendRequest(ComandoComm.vistaLocale.toString() + "," + client.getToken() + "," + client.getGameStatus().idDinoSelected);
		} catch (Exception e) {
			e.printStackTrace();
		}
		info1 = null;
		output.sendMessage("In attesa di risposta dal server");
	}

	public void statoDinosauro() throws RemoteException {
		clientComm.sendRequest(ComandoComm.statoDinosauro.toString() + "," + client.getToken() + "," + client.getGameStatus().idDinoSelected);
		output.sendMessage("In attesa di risposta dal server");
	}

	public void muoviDinosauro() {
		output.sendMessage("Inserisci coordinataX, poi premi invio, poi inserisci coordinataY");
		int posX; int posY;
		readInfo(true);
		try {
			posX = Integer.parseInt(info1);
			posY = Integer.parseInt(info2);
			clientComm.sendRequest(ComandoComm.muoviDinosauro.toString() + "," + client.getToken() + "," +
					client.getGameStatus().idDinoSelected + ",{" + posX + "," + posY + "}");
		} catch (Exception e) {
			e.printStackTrace();
		}
		info1 = null; info2 = null;
		output.sendMessage("In attesa di risposta dal server");
	}

	public void cresciDinosauro() throws RemoteException {
		clientComm.sendRequest(ComandoComm.cresciDinosauro.toString() + "," + client.getToken() + "," + client.getGameStatus().idDinoSelected);
		output.sendMessage("In attesa di risposta dal server");
	}
	
	public void deponiUovo() throws RemoteException {
		clientComm.sendRequest(ComandoComm.deponiUovo.toString() + "," + client.getToken() + "," + client.getGameStatus().idDinoSelected);
		output.sendMessage("In attesa di risposta dal server");
	}

}
